package com.hd.hdxgddcommon.aop;

import com.hd.hdxgddcommon.annotation.api.SysLogBuilder;
import com.hd.hdxgddcommon.aop.entity.LogAnParse;
import com.hd.hdxgddcommon.utils.StringUtils;
import com.hd.hdxgddcommon.utils.SpelUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by Administrator on 2018/4/26.
 * Description : 日志切面
 */
public abstract class LogsAspect {

    /**
     * 获取解析后的描述
     * important!!!
     *
     * @param joinPoint
     * @return
     */
    protected String parseDesc(ProceedingJoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();

        SysLogBuilder annotation = method.getAnnotation(SysLogBuilder.class);
        Object target = joinPoint.getTarget();
        Object[] args = joinPoint.getArgs();

        String desc = annotation.desc();

        Pattern beforePattern = Pattern.compile("#\\{[0-9a-zA-Z\\.]*}");
        Matcher beforeMatcher = beforePattern.matcher(desc);
        List<LogAnParse> beforeSpels = new ArrayList<>();
        match(beforeMatcher, beforeSpels);
        List<LogAnParse> beforeList = SpelUtils.parse(target, beforeSpels, method, args);
        desc = buildDesc(beforeList, desc, "#");

        Pattern returnPattern = Pattern.compile("@\\{[0-9a-zA-Z\\.]*}");
        Matcher returnMatcher = returnPattern.matcher(desc);
        List<LogAnParse> returnSpels = new ArrayList<>();
        match(returnMatcher, returnSpels);
        List<LogAnParse> returnList = SpelUtils.parseReturn(returnSpels);


        if (returnList != null) {
            desc = buildDesc(returnList, desc, "@");
        }
        return desc;
    }

    protected void match(Matcher matcher, List<LogAnParse> spels) {
        while (matcher.find()) {
            LogAnParse logAnParse = new LogAnParse();
            String val = matcher.group();
            logAnParse.setCompleteContent(val);
            spels.add(logAnParse);
        }
    }

    protected String buildDesc(List<LogAnParse> logAnParses, String desc, String head) {
        for (LogAnParse log : logAnParses) {
            String finalValue = log.getFinalValue();
            String completeContent = log.getFinalName(true, head);
            if (StringUtils.isNotBlank(completeContent)) {
                if (finalValue != null) {
                    if (finalValue == "") {
                        finalValue = "''";
                    }
                    desc = desc.replace(completeContent, finalValue);
                } else {
                    desc = desc.replace(completeContent, "null");
                }
            }
        }
        return desc;
    }

    public abstract Object around(ProceedingJoinPoint joinPoint, SysLogBuilder sysLog) throws Throwable;
}
